/**
 * 全屏显示封装
 *
 * 全屏面板的优先级过高，
 *
 * 已知问题，如果全屏局部 dom 元素，并且内部组件调整过 z-index，
 * 一般会悬浮在面板后面，这没什么完美的解决手段，。
 *
 * 在老版本的浏览器中，不同浏览器，全屏的写法各不相同，
 *
 * @author Mr.css
 * @constructor
 */
interface IScreen {
    /**
     * 是否处在全屏状态
     */
    isFullscreen: () => boolean;

    /**
     * 进入全屏状态
     *
     * @param element 允许是任意 dom 元素
     */
    requestFullscreen: (element: HTMLElement = document.documentElement) => void;

    /**
     * 退出全屏状态
     */
    exitFullscreen: () => void;
}

/**
 * 现代浏览器，其它前缀的实现，只是向后兼容，一般用不到
 */
class StandardScreen extends IScreen {
    isFullscreen() {
        return !!document.fullscreenElement;
    }

    async requestFullscreen(element: HTMLElement = document.documentElement) {
        await element.requestFullscreen();
    }

    exitFullscreen() {
        if (this.isFullscreen()) {
            await document.exitFullscreen();
        }
    }
}

class WebkitScreen extends IScreen {
    isFullscreen() {
        return !!document.webkitFullscreenElement;
    }

    requestFullscreen(element: HTMLElement = document.documentElement) {
        element.webkitRequestFullscreen();
    }

    exitFullscreen() {
        if (this.isFullscreen()) {
            await document.webkitExitFullscreen();
        }
    }
}

class MozScreen extends IScreen {
    isFullscreen() {
        return !!document.mozFullScreenElement;
    }

    requestFullscreen(element: HTMLElement = document.documentElement) {
        element.mozRequestFullScreen();
    }

    exitFullscreen() {
        if (this.isFullscreen()) {
            await document.mozCancelFullScreen();
        }
    }
}

class MsScreen extends IScreen {
    isFullscreen() {
        return !!document.msFullscreenElement;
    }

    requestFullscreen(element: HTMLElement = document.documentElement) {
        element.msRequestFullscreen();
    }

    exitFullscreen() {
        if (this.isFullscreen()) {
            await document.msExitFullscreen();
        }
    }
}

// 检测并返回合适的全屏实现
function getScreenImplementation() {
    if (document.documentElement.requestFullscreen) {
        return StandardScreen;
    } else if (document.documentElement.webkitRequestFullscreen) {
        return WebkitScreen;
    } else if (document.documentElement.mozRequestFullScreen) {
        return MozScreen;
    } else if (document.documentElement.msRequestFullscreen) {
        return MsScreen;
    }

    console.error("unknown fullscreen method, maybe cause any exception!");
    return null;
}

const screen:IScreen = getScreenImplementation();
export default screen;
